

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#include <stdio.h>
#include <stdarg.h>

#include "GError.h"

namespace GUtil
{

	/********************************************************/
	/*						GError Routines					*/
	/********************************************************/

	void GError::DebugBreak()
	{
	#if defined (DEBUG) || defined (_DEBUG)
		__debugbreak( );	
	#endif
	}

	void DebugReport(const char* Format, va_list Arguments)
	{
	#if defined (DEBUG) || defined (_DEBUG)
		char ErrorString[G_ERROR_MESSAGE_MAX_LEGTH];

		vsnprintf_s(ErrorString, G_ERROR_MESSAGE_MAX_LEGTH, Format, Arguments);
		_CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, __FUNCTION__, ErrorString);
	#endif
	}

	void GError::DebugCheck(bool Condition, const char* Format, ...)
	{
	#if defined (DEBUG) || defined (_DEBUG)
		if (Condition)
		{
			va_list Arguments;
			va_start(Arguments, Format);

			GFileLogger::GetInstance()->Log(G_LOG_TYPE_ERROR, Format, Arguments);	

			DebugReport(Format, Arguments);
			DebugBreak();

			va_end(Arguments);
		}
	#endif
	}

	void GError::Error(const char* Format, ...)
	{
		va_list Arguments;
		va_start(Arguments, Format);

		GFileLogger::GetInstance()->Log(G_LOG_TYPE_ERROR, Format, Arguments);

	#if defined (DEBUG) || defined (_DEBUG)
		DebugReport(Format, Arguments);
		DebugBreak();
	#else
		GErrorMessage Message(Format, Arguments);
		Message.Display();
	#endif

		va_end(Arguments);
	}

	void GError::Error(const GErrorMessage& Message)
	{
		GFileLogger::GetInstance()->Log(G_LOG_TYPE_ERROR, Message.GetErrorMessage());

	#if defined (DEBUG) || defined (_DEBUG)
		DebugReport( Message.GetErrorMessage(), NULL);
		DebugBreak();
	#else
		Message.Display();
	#endif
	}

	void GError::Exit(const char* Format, ...)
	{
		va_list Arguments;
		va_start(Arguments, Format);

		GFileLogger::GetInstance()->Log(G_LOG_TYPE_ERROR, Format, Arguments);

	#if defined (DEBUG) || defined (_DEBUG)
		DebugReport(Format, Arguments);
		DebugBreak();
	#else			
		GErrorMessage Message(Format, Arguments);
		Message.Display();
	#endif

		va_end(Arguments);
		exit(EXIT_FAILURE);
	}

	void GError::Exit( const GErrorMessage& Message )
	{
		GFileLogger::GetInstance()->Log(G_LOG_TYPE_ERROR, Message.GetErrorMessage());

	#if defined (DEBUG) || defined (_DEBUG)
		DebugReport(Message.GetErrorMessage(), NULL);
		DebugBreak();
	#else
		Message.Display();
	#endif

		exit(EXIT_FAILURE);
	}

	/********************************************************/
	/*						GErrorMessage					*/
	/********************************************************/

	GErrorMessage::GErrorMessage() : Message ("No Message")
	{

	}

	GErrorMessage::GErrorMessage(const char* Format, ...)
	{
		char Arr[G_ERROR_MESSAGE_MAX_LEGTH];
		va_list Args;
		va_start(Args, Format);

		vsnprintf_s(Arr, G_ERROR_MESSAGE_MAX_LEGTH, Format, Args);
		Message = Arr;

		va_end(Args);
	}

	GErrorMessage::~GErrorMessage()
	{

	}
						
	void GErrorMessage::SetErrorMessage(const char* Format, ...)
	{
		char Arr[G_ERROR_MESSAGE_MAX_LEGTH];
		va_list Args;
		va_start(Args, Format);

		vsnprintf_s(Arr, G_ERROR_MESSAGE_MAX_LEGTH, Format, Args);
		Message = Arr;

		va_end(Args);
	}

	const char* GErrorMessage::GetErrorMessage() const
	{
		return Message.c_str();
	}

	void GErrorMessage::Display() const
	{
		MessageBox(0, Message.c_str(), "Error", MB_ABORTRETRYIGNORE | MB_ICONERROR | MB_SYSTEMMODAL);
	}

	/********************************************************/
	/*					GErrorMessageWin32					*/
	/********************************************************/

	GErrorMessageWin32::GErrorMessageWin32() : GErrorMessage("Win32 Error")
	{

	}

	GErrorMessageWin32::GErrorMessageWin32(DWORD ErrorCode)
	{
		SetErrorMessage(ErrorCode);
	}

	GErrorMessageWin32::~GErrorMessageWin32()
	{

	}

	void GErrorMessageWin32::SetErrorMessage(DWORD ErrorCode)
	{
		char ErrorStr[G_ERROR_MESSAGE_MAX_LEGTH];
	
		Message = "Win32 Error: ";

		DWORD Result = FormatMessage(	FORMAT_MESSAGE_FROM_SYSTEM, 
										0, 
										ErrorCode, 
										MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
										ErrorStr, 
										G_ERROR_MESSAGE_MAX_LEGTH, 
										NULL );
	
		if (Result  == 0)
		{
			Message += "Sorry, no error message for this one.";
			return;
		}

		Message = ErrorStr;
	}

}; // namespace GUtil